package com.zcup.miaosha.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zcup.miaosha.entity.Commodity;
import com.zcup.miaosha.entity.Order;
import com.zcup.miaosha.entity.User;
import com.zcup.miaosha.mapper.CommodityMapper;
import com.zcup.miaosha.service.CommodityService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;

import java.util.concurrent.TimeUnit;


@Service
@Transactional
public class CommodityServiceImpl extends ServiceImpl<CommodityMapper,Commodity> implements CommodityService {

    @Autowired
    private OrderServiceImpl orderService;

    @Autowired
    private UserServiceImpl userService;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public int kill(int id) {
        //校验库存
        Commodity commodity = checkSale(id);
        //扣除库存
        updateSale(commodity);
        //创建订单
        return createOrder(commodity);
    }

    @Override
    public int kill(Integer id,Integer userId,String md5) {

        //校验该商品秒杀时长是否超时
        if (Boolean.FALSE.equals(stringRedisTemplate.hasKey("kill" + id))) {
            throw new RuntimeException("当前商品抢购活动已结束");
        }

        //MD5签名验证
        if (!signageMd5(id,userId,md5)) {
            throw new RuntimeException("MD5认证过程出现异常");
        }

        //校验库存
        Commodity commodity = checkSale(id);
        //扣除库存
        updateSale(commodity);
        //创建订单
        return createOrder(commodity);
    }

    @Override
    public String getMd5(Integer id, Integer userId) {
        //生成hashKey
        String hashKey = "KEY_" + userId + "_" + id;

        if (Boolean.TRUE.equals(stringRedisTemplate.hasKey(hashKey))){
            return stringRedisTemplate.opsForValue().get(hashKey);
        }

        //验证用户合法性
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("id",userId);
        if (userService.count(wrapper) == 0) throw new RuntimeException("用户信息不存在");

        //验证商品合法性
        QueryWrapper<Commodity> queryWrapper = new QueryWrapper<>();
        wrapper.eq("id",id);
        if (this.baseMapper.selectCount(queryWrapper) == 0) throw new RuntimeException("商品信息不存在");

        //生成md5
        String key = DigestUtils.md5DigestAsHex((userId + id + "$E3T2").getBytes());
        stringRedisTemplate.opsForValue().set(hashKey,key,60, TimeUnit.SECONDS);
        return key;
    }

    /**
     * 校验库存
     * @param id 商品id
     * @return 商品信息
     */
    private Commodity checkSale(Integer id){
        Commodity commodity = this.baseMapper.selectById(id);
        if (commodity.getCommodityCount() == commodity.getCommoditySale()){
            throw new RuntimeException("库存不足");
        }
        return commodity;
    }

    /**
     * 扣除库存
     * @param commodity 商品信息
     */
    private void updateSale(Commodity commodity){
        if (this.baseMapper.sellGoods(commodity) == 0) throw new RuntimeException("抢购失败");
    }

    /**
     * 创建订单
     * @param commodity 商品信息
     */
    private int createOrder(Commodity commodity){
        Order order = new Order();
        order.setCommodityId(commodity.getId());
        order.setCount(1);
        return orderService.getBaseMapper().createOrder(order);
    }

    private boolean signageMd5(Integer id,Integer userId,String md5){
        String hashKey = "KEY_" + userId + "_" + id;
        String s = stringRedisTemplate.opsForValue().get(hashKey);
        if (s == null || md5 == null) {
            return false;
        }
        return s.equals(md5);
    }
}
